package com.mavenq.fly.interceptor;

import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;

import java.lang.reflect.Field;
import java.sql.Connection;

@Intercepts({
        @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})
})
public class SqlInterceptor implements Interceptor {


    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        BoundSql boundSql = statementHandler.getBoundSql();

        // 更安全的方式获取 MappedStatement
        MappedStatement mappedStatement = getMappedStatement(statementHandler);
        if (mappedStatement != null) {
            String originalSql = mappedStatement.getSqlSource().getBoundSql(boundSql.getParameterObject()).getSql();
            System.out.println("原始SQL: " + originalSql);
        }

        System.out.println("处理后SQL: " + boundSql.getSql());
        return invocation.proceed();
    }

    private MappedStatement getMappedStatement(StatementHandler handler) {
        try {
            // 尝试从 RoutingStatementHandler 获取 delegate
            if (handler instanceof RoutingStatementHandler) {
                Field delegateField = handler.getClass().getDeclaredField("delegate");
                delegateField.setAccessible(true);
                StatementHandler delegate = (StatementHandler) delegateField.get(handler);
                return getMappedStatementFromHandler(delegate);
            }
            return getMappedStatementFromHandler(handler);
        } catch (Exception e) {
            return null;
        }
    }

    private MappedStatement getMappedStatementFromHandler(StatementHandler handler) {
        try {
            Field mappedStatementField = handler.getClass().getDeclaredField("mappedStatement");
            mappedStatementField.setAccessible(true);
            return (MappedStatement) mappedStatementField.get(handler);
        } catch (Exception e) {
            return null;
        }
    }

    // 其他必要方法...
}